#ifndef __OSA_QUEUE_H__
#define __OSA_QUEUE_H__

#include "osa_common.h"

typedef struct osa_queue_t
{
	uint32_t r, w;
    uint32_t size;               // queue size
    uint32_t item_size;          // item size
    uint32_t sem;           // not used in this implementation
    uint8_t *items;
} osa_queue_t;

#define DEFINE_OSA_QUEUE(queue_name, queue_order, item_size) \
	uint8_t queue_name##_mem [ (1<<(queue_order))*(item_size)] = {0}; \
    osa_queue_t queue_name##_data = {0, 0, \
            (1<<(queue_order)), (item_size), \
            0, queue_name##_mem}; \
	osa_queue_t *queue_name = (osa_queue_t *)&queue_name##_data;


/**
	Push data into queue, return 0 if success, < 0 for error code

    \param queue - queue to handle
    \param data - data to push, data size must match the item_size in osa_queue_create
    \return int 0 if success, < 0 for error code
*/
osa_result_t osa_queue_push(osa_queue_t *queue, void *data);

/**
	Pop data from queue, return 0 if success, < 0 for error code

    \param queue - queue to handle
    \param data - pointer to the popped data, data size must match the item_size in osa_queue_create
    \return int 0 if success, < 0 for error code
*/
osa_result_t osa_queue_pop(osa_queue_t *queue, void *data);

void osa_queue_clear(osa_queue_t *queue);

bool osa_queue_is_full(osa_queue_t *queue);
bool osa_queue_is_empty(osa_queue_t *queue);

#endif /* __OSA_QUEUE_H__ */

